﻿using System;
using System.Collections.Generic;
using System.Text;
using Eb;
using Es;

public class DefChannelService : ComponentDef
{
    //---------------------------------------------------------------------
    public override void defAllProp(Dictionary<string, string> map_param)
    {
    }
}

public class LoginChannelService<T> : Component<T> where T : DefChannelService, new()
{
    //-------------------------------------------------------------------------
    Dictionary<string, LoginInfo> mMapLoginInfo = new Dictionary<string, LoginInfo>();// key=token

    //-------------------------------------------------------------------------
    public LoginUCenter<DefUCenter> CoUCenter { get; private set; }
    public LoginChannelProject<DefChannelProject> CoChannelProject { get; private set; }
    public string NodeTypeString { get; private set; }
    public byte NodeType { get; private set; }
    public string NodeId { get; private set; }// 21
    public string NodeMQ { get; private set; }// "Dragon1_1.00.005_Base_21"

    //-------------------------------------------------------------------------
    public override void init()
    {
        Entity et_project = Entity.Parent;
        CoChannelProject = et_project.getComponent<LoginChannelProject<DefChannelProject>>();
        CoUCenter = CoChannelProject.CoUCenter;

        NodeId = (string)Entity.getCacheData("NodeId");
        NodeTypeString = (string)Entity.getCacheData("NodeTypeString");
        NodeType = (byte)Entity.getCacheData("NodeType");
        NodeMQ = CoChannelProject.ProjectId + "_" + NodeTypeString + "_" + NodeId.ToString();

        EbLog.Note("LoginChannelService.init() NodeMQ=" + NodeMQ);

        CoUCenter.addChannelService(this);
    }

    //-------------------------------------------------------------------------
    public override void release()
    {
        CoUCenter.removeChannelService(this);

        EbLog.Note("LoginChannelService.release() NodeMQ=" + NodeMQ);
    }

    //-------------------------------------------------------------------------
    public override void update(float elapsed_tm)
    {
        // 超时计算
        //mMapLoginInfo
    }

    //-------------------------------------------------------------------------
    public override void handleEvent(object sender, EntityEvent e)
    {
    }

    //-------------------------------------------------------------------------
    public LoginInfo client2ucenterLogin(string account, string password,
        Dictionary<string, string> map_param, IRpcCallerSession client_session)
    {
        // 生成登陆包，跟进登陆流程
        LoginInfo login_info = new LoginInfo();
        login_info.token = Guid.NewGuid().ToString();
        login_info.acc_id = 0;
        login_info.acc = account;
        login_info.pwd = password;
        login_info.map_param = map_param;
        login_info.login_result = eLoginResult.unknow;
        login_info.login_process = LoginProcess.VerifyRequest;
        login_info.client_session = client_session;
        mMapLoginInfo[login_info.token] = login_info;
        return login_info;
    }

    //-------------------------------------------------------------------------
    public void onDbVerify(string token, ulong acc_id, string acc, eLoginResult result, Dictionary<string, string> map_param)
    {
        LoginInfo login_info;
        if (!mMapLoginInfo.TryGetValue(token, out login_info))
        {
            EbLog.Error("LoginChannelService.onDbVerify() not found token=" + token);
            return;
        }
        login_info.login_result = result;
        if (result != eLoginResult.success)
        {
            mMapLoginInfo.Remove(token);
            if (login_info.client_session != null)
            {
                ClientLoginResponse client_login_response = new ClientLoginResponse();
                client_login_response.result = result;
                client_login_response.acc_id = login_info.acc_id;
                client_login_response.token = login_info.token;
                client_login_response.acc = login_info.acc;
                client_login_response.map_param = login_info.map_param;
                rpcBySession(login_info.client_session, (ushort)_eUCenterMethodType.login2clientOnLogin, client_login_response);
            }
        }
        else
        {
            // 发送登陆请求
            login_info.acc_id = acc_id;
            LoginData login_data;
            login_data.token = login_info.token;
            login_data.acc_id = login_info.acc_id;
            login_data.acc = login_info.acc;
            login_data.pwd = login_info.pwd;
            login_data.map_param = login_info.map_param;
            login_data.ucenter_mq = EsEngine.Instance.NodeMQ;
            login_data.service_mq = NodeMQ;
            login_data.service_result = false;

            rpcByMQ(NodeMQ, (ushort)_eUCenterMethodType.login2projectLogin, login_data);

            EbLog.Note("登陆验证step 5 of 6: 请求Service验证, NodeMQ=" + NodeMQ + " Acc=" + acc);
        }
    }

    //-------------------------------------------------------------------------
    public void project2ucenterRecvData(LoginData login_data)
    {
        LoginInfo login_info;
        if (mMapLoginInfo.TryGetValue(login_data.token, out login_info))
        {
            mMapLoginInfo.Remove(login_info.token);
        }
        else
        {
            EbLog.Error("LoginChannelService.project2ucenterRecvData() not found token=" + login_data.token);
            return;
        }

        if (login_data.service_result)
        {
            login_info.login_result = eLoginResult.success;
        }
        else
        {
            login_info.login_result = eLoginResult.serverReject;
        }
        login_info.map_param = login_data.map_param;

        if (login_info.client_session != null)
        {
            EbLog.Note("登陆验证step 6 of 6: Service验证完成, 给客户端发送登陆结果。 NodeMQ=" + NodeMQ + " Acc=" + login_info.acc);

            ClientLoginResponse client_login_response = new ClientLoginResponse();
            client_login_response.result = login_info.login_result;
            client_login_response.acc_id = login_info.acc_id;
            client_login_response.token = login_info.token;
            client_login_response.acc = login_info.acc;
            client_login_response.map_param = login_info.map_param;
            rpcBySession(login_info.client_session, (ushort)_eUCenterMethodType.login2clientOnLogin, client_login_response);
        }
    }
}
